package com.cxx.purchasecharge.component.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cxx.purchasecharge.component.bean.BaseBean;
import com.cxx.purchasecharge.component.bean.DataGridRequestForm;
import com.cxx.purchasecharge.component.bean.GenericPagingResult;
import com.cxx.purchasecharge.component.bean.GoodsBean;
import com.cxx.purchasecharge.component.bean.GoodsStorageBean;
import com.cxx.purchasecharge.component.bean.GoodsStorageCourseBean;
import com.cxx.purchasecharge.component.utils.BeanConvertUtils;
import com.cxx.purchasecharge.core.model.GoodsStorageCourse;
import com.cxx.purchasecharge.core.model.GoodsStorageCourseSearchForm;
import com.cxx.purchasecharge.core.model.persistence.Goods;
import com.cxx.purchasecharge.core.model.persistence.GoodsStorage;
import com.cxx.purchasecharge.core.model.persistence.GoodsType;
import com.cxx.purchasecharge.dal.GoodsDao;
import com.cxx.purchasecharge.dal.GoodsStorageDao;
import com.cxx.purchasecharge.dal.GoodsTypeDao;

@Controller
@RequestMapping ("/goodsStorage")
public class GoodsStorageManager extends GenericController <GoodsStorageBean>
{
    private static final Logger logger = Logger.getLogger (GoodsStorageManager.class);

    @Autowired
    private GoodsStorageDao storageDao;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private GoodsTypeDao goodsTypeDao;

    public GoodsStorageManager()
    {
        super.setViewName("goodsStorageManagement");
    }

    /*@Override
    public String getAllModel(DataGridRequestForm dataGridRequestForm, HttpServletRequest request)
    {
        List <GoodsStorageBean> goodsStorageBeans = new ArrayList <GoodsStorageBean> ();
        List <Goods> goodsList = (List <Goods>) goodsDao.findAll ();
        if (CollectionUtils.isNotEmpty (goodsList))
        {
            List <GoodsType> goodsTypes = (List <GoodsType>) goodsTypeDao.findAll ();
            for (GoodsType goodsType : goodsTypes)
            {
                if (null != goodsType && null == goodsType.getParent ())
                {
                    goodsStorageBeans.add (goodsType2GoodsStorageBean (goodsType));
                }
            }

            for (Goods goods : goodsList)
            {
                if (null == goods.getType ())
                {
                    goodsStorageBeans.add (BeanConvertUtils.storage2StorageBean (goods.getStorage ()));
                }
            }
        }

        JSONArray jsonArr = JSONArray.fromObject (goodsStorageBeans);
        return jsonArr.toString ();
    }

    @Override
    public String addModel(GoodsStorageBean bean, BindingResult bindingResult, HttpServletRequest request)
    {
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            GoodsStorage storage = BeanConvertUtils.storageBean2Storage (bean);
            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                storageDao.save (storage);
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_ADD_SUCCESS,
                                                                                     ComponentConstants.MSG_GOODS_STORAGE))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_ADD_FAIL,
                                                                                     ComponentConstants.MSG_GOODS_STORAGE))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
    }

    @Override
    public String updateModel(GoodsStorageBean bean, BindingResult bindingResult, HttpServletRequest request)
    {
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            GoodsStorage storage = BeanConvertUtils.storageBean2Storage (bean);
            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                storageDao.save (storage);
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_UPDATE_SUCCESS,
                                                                                     ComponentConstants.MSG_GOODS_STORAGE))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_UPDATE_FAIL,
                                                                                     ComponentConstants.MSG_GOODS_STORAGE))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
    }*/

    /*@RequestMapping (value = "/asyncGetStorages", method = RequestMethod.POST)
    public @ResponseBody
    String asyncGetStorages (BaseBean baseBean)
    {
        List <GoodsStorageBean> goodsStorageBeans = new ArrayList <GoodsStorageBean> ();
        if (StringUtils.isBlank (baseBean.getId ()))
        {
            List <Goods> goodsList = (List <Goods>) goodsDao.findAll ();
            if (CollectionUtils.isNotEmpty (goodsList))
            {
                List <GoodsType> goodsTypes = (List <GoodsType>) goodsTypeDao.findAll ();
                for (GoodsType goodsType : goodsTypes)
                {
                    if (null != goodsType && null == goodsType.getParent ())
                    {
                        goodsStorageBeans.add (goodsType2GoodsStorageBean (goodsType));
                    }
                }

                for (Goods goods : goodsList)
                {
                    if (null == goods.getType ())
                    {
                        goodsStorageBeans.add (BeanConvertUtils.storage2StorageBean (goods.getStorage ()));
                    }
                }
            }
        }
        else
        {
            List <GoodsType> goodsTypes = goodsTypeDao.findByParent (Long.parseLong (baseBean.getId ()));
            if (CollectionUtils.isNotEmpty (goodsTypes))
            {
                for (GoodsType goodsType : goodsTypes)
                {
                    goodsStorageBeans.add (goodsType2GoodsStorageBean (goodsType));
                }
            }
        }

        JSONArray jsonArr = JSONArray.fromObject (goodsStorageBeans);
        return jsonArr.toString ();
    }*/
    
    @RequestMapping (value = "/asyncGetStorages", method = RequestMethod.POST)
    public @ResponseBody
    String asyncGetStorages (BaseBean baseBean, String searchKey)
    {
        if(StringUtils.isNotBlank(searchKey)) 
        {
            GenericPagingResult <GoodsStorageBean> goodsPagingResult = new GenericPagingResult <GoodsStorageBean> ();
            List <GoodsStorageBean> goodsBeans = new ArrayList <GoodsStorageBean> ();
            List <Goods> goodses = goodsDao.findByFuzzyName(searchKey);
            List <GoodsStorage> goodsResult = new ArrayList <GoodsStorage> ();
            for(Goods goods : goodses) 
            {
                Goods dbGoods = goodsDao.findOne (goods.getId ());
                goodsResult.add (dbGoods.getStorage ());
            }
            goodsBeans.addAll (BeanConvertUtils.storageList2StorageBeanList (goodsResult));
            goodsPagingResult.setRows (goodsBeans);
            long count = goodsBeans.size();
            goodsPagingResult.setTotal (count);
            List<Map <String, String>> footer = new ArrayList <Map<String,String>> ();
            Map<String, String> map = new HashMap <String, String> ();
            map.put ("iconCls", "icon-sum");
            map.put ("name", "货物合计：" + count);
            footer.add (map);
            goodsPagingResult.setFooter (footer);
            JSONObject jsonObject = JSONObject.fromObject (goodsPagingResult);
            return jsonObject.toString ();
        }
        
        List <GoodsStorageBean> goodsStorageBeans = new ArrayList <GoodsStorageBean> ();
        if (StringUtils.isBlank (baseBean.getId ()))
        {
            List <Goods> goodsList = (List <Goods>) goodsDao.findAll ();
            if (CollectionUtils.isNotEmpty (goodsList))
            {
                for (Goods goods : goodsList)
                {
                    if (null == goods.getType ())
                    {
                        goodsStorageBeans.add (BeanConvertUtils.storage2StorageBean (goods.getStorage ()));
                    }
                }
                
                List <GoodsType> goodsTypes = (List <GoodsType>) goodsTypeDao.findAll ();
                if(CollectionUtils.isNotEmpty (goodsTypes)) 
                {
                    for (GoodsType goodsType : goodsTypes)
                    {
                        if (null != goodsType && null == goodsType.getParent ())
                        {
                            goodsStorageBeans.add (goodsType2GoodsStorageBean2 (goodsType));
                        }
                    }
                }
            }
            
            GenericPagingResult <GoodsStorageBean> goodsPagingResult = new GenericPagingResult <GoodsStorageBean> ();
            goodsPagingResult.setRows (goodsStorageBeans);
            long count = goodsDao.count ();
            goodsPagingResult.setTotal (count);
            List<Map <String, String>> footer = new ArrayList <Map<String,String>> ();
            Map<String, String> map = new HashMap <String, String> ();
            map.put ("iconCls", "icon-sum");
            map.put ("goodsName", "货物合计：" + count);
            footer.add (map);
            goodsPagingResult.setFooter (footer);
            JSONObject jsonObject = JSONObject.fromObject (goodsPagingResult);
            return jsonObject.toString ();
        }
        else
        {
            List <GoodsType> goodsTypes = goodsTypeDao.findByParent (Long.parseLong (baseBean.getId ()));
            if (CollectionUtils.isNotEmpty (goodsTypes))
            {
                for (GoodsType goodsType : goodsTypes)
                {
                    goodsStorageBeans.add (goodsType2SingleGoodsStorageBean (goodsType));
                }
            }
            
            GoodsType goodsType = new GoodsType();
            goodsType.setId(Long.parseLong (baseBean.getId ()));
            List<Goods> goodses = goodsDao.findByType(goodsType);
            if(CollectionUtils.isNotEmpty (goodses)) 
            {
                for(Goods goods : goodses) 
                {
                    goodsStorageBeans.add (BeanConvertUtils.storage2StorageBean (goods.getStorage ()));
                }
            }
            JSONArray jsonArr = JSONArray.fromObject (goodsStorageBeans);
            return jsonArr.toString ();
        }
    }

    @RequestMapping (value = "/getStorageCourse", method = RequestMethod.POST)
    public @ResponseBody
    String getStorageCourse (DataGridRequestForm dataGridRequestForm, @RequestParam String goodsId)
    {
        GenericPagingResult <GoodsStorageCourseBean> goodsPagingResult = new GenericPagingResult <GoodsStorageCourseBean> ();
        if (StringUtils.isNotBlank (goodsId))
        {
            int page = dataGridRequestForm.getPage () - 1;
            int size = dataGridRequestForm.getRows ();
            Pageable pageable = new PageRequest (page, size);
            
            GoodsStorageCourseSearchForm searchForm = new GoodsStorageCourseSearchForm ();
            searchForm.setGoodsId (Long.parseLong (goodsId));
            Page <GoodsStorageCourse> goodsPage = goodsDao.findGoodsStorageCourse (pageable, searchForm);
            
            goodsPagingResult.setTotal (goodsPage.getTotalElements ());
            
            List <GoodsStorageCourse> goodsStorageCourses = goodsPage.getContent ();
            List <GoodsStorageCourseBean> goodsStorageCourseBeans = new ArrayList <GoodsStorageCourseBean> ();
            for (GoodsStorageCourse goodsStorageCourse : goodsStorageCourses)
            {
                goodsStorageCourseBeans.add (BeanConvertUtils.goodsStorageCourse2GoodsStorageCourseBean (goodsStorageCourse));
            }
            goodsPagingResult.setRows (goodsStorageCourseBeans);
        }
        
        JSONObject jsonObject = JSONObject.fromObject (goodsPagingResult);
        return jsonObject.toString ();
    }
    
    @RequestMapping (value = "/getStorageRest", method = RequestMethod.POST)
    public @ResponseBody
    String getStorageRest (@RequestParam String showRest)
    {
        List<Goods> allGoods = (List<Goods>)goodsDao.findAll();
        List<Goods> restGoods = new ArrayList<Goods>();
        if(CollectionUtils.isNotEmpty(allGoods)) 
        {
            if("1".equals (showRest)) 
            {
                for(Goods goods : allGoods)
                {
                    if(null != goods.getStorage() && goods.getStorage().getCurrentStock() > 0) 
                    {
                        restGoods.add(goods);
                    }
                }
            }
            else 
            {
                restGoods = allGoods;
            }
        }
        
        List<GoodsBean> restGoodsBeans = BeanConvertUtils.goodsList2GoodsBeanList(restGoods);
        GenericPagingResult <GoodsBean> goodsPagingResult = new GenericPagingResult <GoodsBean> ();
        goodsPagingResult.setTotal (restGoodsBeans.size());
        goodsPagingResult.setRows (restGoodsBeans);

        JSONObject jsonObject = JSONObject.fromObject (goodsPagingResult);
        return jsonObject.toString ();
    }

    private GoodsStorageBean goodsType2GoodsStorageBean (GoodsType goodsType)
    {
        GoodsStorageBean goodsStorageBean = new GoodsStorageBean ();
        if (null != goodsType.getParent ())
        {
            GoodsBean goodsBean = new GoodsBean ();
            goodsBean.setName (goodsType.getName ());
            goodsStorageBean.setGoodsBean (goodsBean);
            goodsStorageBean.setId (goodsType.getId () + "");
            goodsStorageBean.setGoods (false);

            List <Goods> goodsList = goodsDao.findByType (goodsType);
            List <GoodsStorageBean> children = new ArrayList <GoodsStorageBean> ();
            if (CollectionUtils.isNotEmpty (goodsList))
            {
                for (Goods goods : goodsList)
                {
                    children.add (BeanConvertUtils.storage2StorageBean (goods.getStorage ()));
                }
            }

            List <GoodsType> goodsTypes = goodsTypeDao.findByParent (goodsType.getId ());
            if (CollectionUtils.isNotEmpty (goodsTypes))
            {
                for (GoodsType gt : goodsTypes)
                {
                    children.add (goodsType2GoodsStorageBean (gt));
                }
            }
            goodsStorageBean.setChildren (children);
        }
        else
        {
            GoodsBean goodsBean = new GoodsBean ();
            goodsBean.setName (goodsType.getName ());
            goodsStorageBean.setGoodsBean (goodsBean);
            goodsStorageBean.setId (goodsType.getId () + "");
            goodsStorageBean.setGoods (false);

            List <Goods> goodsList = goodsDao.findByType (goodsType);
            List <GoodsStorageBean> children = new ArrayList <GoodsStorageBean> ();
            if (CollectionUtils.isNotEmpty (goodsList))
            {
                for (Goods goods : goodsList)
                {
                    children.add (BeanConvertUtils.storage2StorageBean (goods.getStorage ()));
                }
            }

            List <GoodsType> goodsTypes = goodsTypeDao.findByParent (goodsType.getId ());
            if (CollectionUtils.isNotEmpty (goodsTypes))
            {
                for (GoodsType gt : goodsTypes)
                {
                    children.add (goodsType2GoodsStorageBean (gt));
                }
            }
            goodsStorageBean.setChildren (children);
        }
        return goodsStorageBean;
    }
    
    private GoodsStorageBean goodsType2GoodsStorageBean2 (GoodsType goodsType)
    {
        GoodsStorageBean goodsStorageBean = new GoodsStorageBean ();
        if (null != goodsType.getParent ())
        {
            GoodsBean goodsBean = new GoodsBean ();
            goodsBean.setName (goodsType.getName ());
            goodsStorageBean.setGoodsBean (goodsBean);
            goodsStorageBean.setId (goodsType.getId () + "");
            goodsStorageBean.setGoods(false);
            List<Goods> goodses = goodsDao.findByType(goodsType);
            if(CollectionUtils.isEmpty (goodses)) 
            {
                goodsStorageBean.setState ("open");
                List <GoodsStorageBean> children = new ArrayList <GoodsStorageBean> ();
                List <GoodsType> list = goodsTypeDao.findByParent (goodsType.getId ());
                if(CollectionUtils.isNotEmpty (list)) 
                {
                    for (GoodsType type : list)
                    {
                        children.add (goodsType2GoodsStorageBean2 (type));
                    }
                }
                goodsStorageBean.setChildren (children);
            }
        }
        else
        {
            GoodsBean goodsBean = new GoodsBean ();
            goodsBean.setName (goodsType.getName ());
            goodsStorageBean.setGoodsBean (goodsBean);
            goodsStorageBean.setId (goodsType.getId () + "");
            goodsStorageBean.setGoods(false);
            List<Goods> goodses = goodsDao.findByType(goodsType);
            if(CollectionUtils.isEmpty (goodses)) 
            {
                goodsStorageBean.setState ("open");
                List <GoodsStorageBean> children = new ArrayList <GoodsStorageBean> ();
                List <GoodsType> list = goodsTypeDao.findByParent (goodsType.getId ());
                if(CollectionUtils.isNotEmpty (list)) 
                {
                    for (GoodsType type : list)
                    {
                        children.add (goodsType2GoodsStorageBean2 (type));
                    }
                }
                goodsStorageBean.setChildren (children);
            }
        }
        
        return goodsStorageBean;
    }
    
    private GoodsStorageBean goodsType2SingleGoodsStorageBean(GoodsType goodsType) 
    {
        if(null != goodsType) 
        {
            GoodsStorageBean goodsStorageBean = new GoodsStorageBean ();
            GoodsBean goodsBean = new GoodsBean ();
            goodsBean.setName (goodsType.getName ());
            goodsStorageBean.setGoodsBean (goodsBean);
            goodsStorageBean.setId (goodsType.getId () + "");
            goodsStorageBean.setGoods(false);
            List<Goods> goodses = goodsDao.findByType(goodsType);
            if(CollectionUtils.isEmpty (goodses)) 
            {
                goodsStorageBean.setState ("open");
            }
            return goodsStorageBean;
        }
        return null;
    }

}
